package com.bjzh.bjzh.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bjzh.bjzh.commandManager.CommandManager;
import com.bjzh.bjzh.commandManager.CommandManagerImpl;
import com.bjzh.bjzh.commandManager.commandbuidler.CommandBuidlerFactory;
import com.bjzh.bjzh.common.utils.R;
import com.bjzh.bjzh.common.utils.RedisUtils;
import com.bjzh.bjzh.servers.Jtt809NettyClient;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;

@RestController
@RequestMapping("/api/hysp")
public class hyspController {
    @Value("${bjzh.hysp.apiUrl}")
    private String APIURL;
    @Value("${bjzh.hysp.username}")
    private String username;
    @Value("${bjzh.hysp.password}")
    private String password;
    @Value("${bjzh.hysp.clientId}")
    private String clientId;
    private static   CommandManager manager;
    @Autowired
    private RedisUtils redisUtils;

    static {
         manager=new CommandManagerImpl(10);
    }

    @GetMapping("/devList")
    @ApiOperation(value = "获取所有设备")
    public String devList() {
        JSONObject jsonObject = new JSONObject().set("clientId",clientId).set("countOnOffLine",1).set("type","0");
        return sendPost("uas/v1/api/dev/list", jsonObject);
    }


    @GetMapping("/live")
    @ApiOperation(value = "根据cameraId获取实时rtsp视频流")
    public R live(@RequestParam(name = "cameraId")@ApiParam(value = "摄像头ID") String cameraId,@RequestParam(name = "streamType")@ApiParam(value = "码流类型(多码流时使用) 1表示主码流\n2表示子码流\n3表示第三码流") Integer streamType,@RequestParam(name = "urlType")@ApiParam(value = "所请求的URL类型，默认值为1 \n1表示rtsp格式的URL\n2表示http格式的URL\n3表示rtmp格式的URL\n") Integer urlType) {
        String flag = redisUtils.get(cameraId);
        if (Boolean.valueOf(flag)){
            return  R.ok().put("url","http://222.244.144.181:8002/hls/"+cameraId+"/"+cameraId+".m3u8").put("taskId",cameraId);
        }
        JSONObject jsonObject = new JSONObject().set("cameraId",cameraId).set("streamType",streamType).set("urlType",urlType).set("agentType",1);
        String s = sendPost("mss/v1/api/media/live", jsonObject);
        System.err.println(s);
        JSONObject rtsp = JSONUtil.parseObj(s);
        System.err.println(rtsp.toString());
        String resultCode =  rtsp.get("resultCode").toString();
        if (!(StrUtil.equals("00000000",resultCode)||StrUtil.equals("0",resultCode))){
            return  R.error( rtsp.get("resultDesc").toString());
        }
        String rtspUrl = (String) rtsp.get("url");
        File file=new File("D:\\jbhs\\nginx-1.12.2\\hls\\hls\\"+cameraId);
        file.mkdir();
        System.err.println("准备进行转码");
        String start = manager.start(cameraId, CommandBuidlerFactory.createBuidler().add("ffmpeg").add("-f", "rtsp").add("-rtsp_transport", "tcp").add("-i", rtspUrl).add("-codec", "copy").add("-f", "hls").add("-hls_list_size", "10").add("-hls_flags", "10").add("-hls_time", "15").add("D:\\jbhs\\nginx-1.12.2\\hls\\hls\\" + cameraId + "\\" + cameraId + ".m3u8"));
        System.err.println("转码开始"+start);


//        CommandLineOperations.start(taskId, "ffmpeg -f rtsp -rtsp_transport tcp -i \""+rtspUrl+"\" -codec copy -f hls  -hls_list_size 10  -hls_time 15 C:\\nginx-1.12.2\\hls\\"+cameraId+".m3u8");
        redisUtils.set(cameraId,"true",59L);
        String vedioList = redisUtils.get("vedioList");
        JSONArray list=null;
        list= StrUtil.isBlank(vedioList)?new JSONArray(): JSONUtil.parseArray(vedioList);
        if (!list.contains(cameraId)) {
            list.add(cameraId);
        }

        redisUtils.set("vedioList",list.toString());
        System.err.println("jedis写入");
        return R.ok().put("url","http://222.244.144.181:8002/hls/"+cameraId+"/"+cameraId+".m3u8").put("taskId",cameraId);
    }


    @GetMapping("/videoKeepAlive")
    @ApiOperation(value = "获取所有设备")
    public R videoKeepAlive(@RequestParam(name = "cameraId")@ApiParam(value = "摄像头ID") String taskId) {
        redisUtils.set(taskId,"true",59L);
        return R.ok();
    }


    @Scheduled(fixedRate = 30000)
    @Async
    void stopVideos(){
        Jtt809NettyClient.sendLinkTestMessage();
    }
        /**
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss");
        Jtt809NettyClient.sendLocationMessage(new JSONObject().set("carnumber","浙CM3397").set("time",simpleDateFormat.format(new Date(System.currentTimeMillis()))).set("lng",25.15466).set("lat",120.561566).set("speed",250).set("dir",230).set("status",1));
    }
*/
    @Scheduled(fixedRate = 60000)
    public void stopVideo(){
        System.err.println("定时任务执行，开始尝试关闭线程");
        String vedioList = redisUtils.get("vedioList");
        JSONArray list = JSONUtil.parseArray(vedioList);
        System.err.println(list);
//        JedisUtil.set("vedioList", Arrays.toString(new String[]));
        if (0==list.size()){
            return;
        }
        System.err.println("-------------------------"+list.toString());
        for (int i = 0; i < list.size(); i++) {
            String s= list.get(i).toString();

            Boolean flag = Boolean.valueOf(redisUtils.get(s));
            if (!flag){
                System.err.println("尝试关闭"+s);
                manager.stop(s);
                File file=new File("D:\\jbhs\\nginx-1.12.2\\hls\\hls\\"+s);
                boolean b = delFiles(file);
                System.err.println("删除文件"+s+"结果为"+b);
                list.remove(s);
            }
        }
        redisUtils.set("vedioList",list.toString());
    }




    public static boolean delFiles(File file){
        boolean result = false;
        //目录
        if(file.isDirectory()){
            File[] childrenFiles = file.listFiles();
            for (File childFile:childrenFiles){
                result = delFiles(childFile);
                if(!result){
                    return result;
                }
            }
        }
        //删除 文件、空目录
        result = file.delete();
        return result;
    }


    protected String sendPost(String apiUri, JSONObject param) {
        HttpRequest post = HttpUtil.createPost(APIURL + apiUri);
        if (ObjectUtil.isNotNull(param)) {
            post.body(param.toString());
        }
        HttpResponse execute = post.execute();
        if (401 == execute.getStatus()) {
            String header = execute.header("WWW-Authenticate");
            String[] strings = StrUtil.splitToArray(header, ',');
            JSONObject jsonObject = new JSONObject();
            for (String string : strings) {
                String[] split = string.split("=");
                jsonObject.set(split[0], split[1]);
            }
            String s = getResponse(username, password, jsonObject.get("Digest realm").toString(), APIURL + apiUri, jsonObject.get("nonce").toString(), "00000001", RandomUtil.randomString(32), jsonObject.get("qop").toString(), jsonObject.get("opaque").toString());
            post.header("Authorization", s);
            execute = post.execute();


        }
        return execute.body();
    }





    private String getResponse(String userName, String password, String realm, String digestURI, String nonce, String nc, String cnonce, String qop, String opaque) {

        String A1 = userName + ":" + realm + ":" + password;
        String A2 = "POST:" + digestURI;
        String HA1 = DigestUtil.md5Hex(A1);
        String HA2 = DigestUtil.md5Hex(A2);
        String A3 = HA1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + HA2;
        String HA3 = DigestUtil.md5Hex(A3).toLowerCase();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder

                .append("Digest realm=\"").append(realm)
                .append("\", username=\"").append(userName)
                .append("\", nonce=\"").append(nonce)
                .append("\", uri=\"").append(digestURI)
                .append("\", algorithm=\"").append("MD5")
                .append("\", qop=\"").append(qop)
                .append("\", nc=\"").append(nc)
                .append("\", cnonce=\"").append(cnonce)
                .append("\", opaque=\"").append(opaque)
                .append("\", response=\"").append(HA3).append("\"");
        return stringBuilder.toString();
    }
}
